//////////////////////////////////////////////////////////
//该程序实现时间计数，校时
//////////////////////////////////////////////////////////
module counter(rst,clk_out1,out[23:0],date[23:0],key_out[2:0]);
input clk_out1,rst;
output [23:0] out,date;
//output lowalarm,highalarm;
input [2:0] key_out;
reg [23:0] out,date;
reg [2:0] state=3'd0;


//外部条件（按键）控制状态机 状态 0-4
always @(negedge key_out[0] or negedge rst)
begin
	if(!rst)
	begin
		state<=3'd0;
	end
	else 
	if(state==3'd4)
		state<=3'd0;
	if(key_out[0]==0)
	state<=state+1;
end

/*状态机*/
always @(posedge clk_out1 or negedge rst)
begin
if(!rst)  //复位
begin
	out<=24'd0;
	date<=24'h19_0509;
end
else
begin
case (state)
//正常计时
3'd0:begin
	out[3:0]<=out[3:0]+1;
	if(out[3:0]==4'd9)
		begin	
			out[3:0]<=4'd0;
			out[7:4]<=out[7:4]+1;
			if(out[7:4]==4'd5)	
		 begin 
			out[7:4]<=4'd0;
			out[11:8]<=out[11:8]+1;
			if(out[11:8]==4'd9)
			begin 
				out[11:8]<=4'd0;
				out[15:12]<=out[15:12]+1;
				if(out[15:12]==4'd5)
				begin
					out[15:12]<=4'd0;
					out[19:16]<=out[19:16]+1;
					if(out[19:16]==4'd9)
					begin 
						out[19:16]<=4'd0;
						out[23:20]<=out[23:20]+1;
						if((out[23:20]==4'd2)&&(out[19:16]==4'd3)&&(out[15:12]==4'd5)&&(out[11:8]==9)&&(out[7:4]==4'd5)&&(out[3:0]==4'd9))
						begin
							out[23:0]<=24'd0;
							date[3:0]<=date[3:0]+1;
							if(date[3:0]==4'd9)
							begin
								date[7:4]<=date[7:4]+1;
								date[3:0]<=4'd0;
							end
							if(date[7:0]==8'h31)
							begin
								date[7:0]<=8'd1;
								date[11:8]<=date[11:8]+1;
								if(date[11:8]==4'd9)
								begin
									date[11:8]<=4'd0;
									date[15:12]<=date[15:12]+1;
								end
								if(date[15:8]==8'h12 && date[7:0]==8'h31)
								begin
									date[19:16]<=date[19:16]+1;
									date[15:8]<=8'd1;
									if(date[19:16]==4'd9)
									date[23:20]<=date[23:20]+1;
								end	
							end
						end
					end
				end
			end
		 end
		
		end
	
end

/*
调整秒
*/
3'd1: 
begin
if(key_out[1]==0)
	begin
	out[3:0]<=out[3:0]+1;
	if(out[3:0]==9)
		begin	
			out[3:0]<=4'd0;
			out[7:4]<=out[7:4]+1;
			if(out[7:4]==5)	
			begin 
				out[7:0]<=8'd0;
			end
		end
	end
end
/*
调整分
*/
3'd2:
begin
if(key_out[1]==0)
begin
	out[11:8]<=out[11:8]+1;
	if(out[11:8]==9)
		begin	
			out[11:8]<=4'd0;
			out[15:12]<=out[15:12]+1;
			if(out[15:12]==5)	
			begin 
				out[15:8]<=8'd0;
			end
		end
	end
end

/*
调整小时
*/
3'd3:
begin
if(key_out[1]==0)
begin
	out[19:16]<=out[19:16]+1;
	if(out[19:16]==9)
		begin 
			out[19:16]<=4'd0;
			out[23:20]<=out[23:20]+1;
			if(out[23:20]==4'd2)
			begin
				out[23:16]<=8'd0;
			end	
		end
		
	if((out[23:20]==4'd2)&&(out[19:16]==4'd3))
	begin
	out[23:16]<=8'd0;
	end
end

end

/*调整天数*/
3'd4:
begin
if(key_out[1]==0)
begin
	date[3:0]<=date[3:0]+1;
	if(date[3:0]==4'd9)
		begin
			date[7:4]<=date[7:4]+1;
			date[3:0]<=4'd0;
		end
		if(date[7:0]==8'h31)
		begin
			date[7:0]<=8'd1;
			date[11:8]<=date[11:8]+1;
			if(date[11:8]==4'd9)
			begin
				date[11:8]<=4'd0;
				date[15:12]<=date[15:12]+1;
			end
			if(date[15:8]==8'h12 && date[7:0]==8'h31)
			begin
				date[19:16]<=date[19:16]+1;
				date[15:8]<=8'd1;
				if(date[19:16]==4'd9)
				date[23:20]<=date[23:20]+1;
			end	
	end
end
end

//m
3'd5:
begin
if(key_out[1]==0)
begin
	date[11:8]<=date[11:8]+1;
	if(date[11:8]==4'd9)
	begin
		date[11:8]<=4'd0;
		date[15:12]<=date[15:12]+1;
	end
	if(date[15:8]==8'h12)
	begin
		date[15:8]<=8'd1;
	end
	if(date[15:8]==8'h12 && date[7:0]==8'h31)
	begin
		date[19:16]<=date[19:16]+1;
		date[15:8]<=8'd1;
		if(date[19:16]==4'd9)
		date[23:20]<=date[23:20]+1;
	end	
end
end

endcase

end

end

/*整点报时
always @(posedge clk_out1)
begin
	if(!rst)
	begin
		lowalarm<=0;
	end
	else
	begin
		if((out[15:12]==4'd5)&&(out[11:8]==4'd9))
		begin
			if(out[7:4]==4'd5)
			begin
			 if((out[3:0]==4'd1)||(out[3:0]==4'd3)||(out[3:0]==4'd5)||(out[3:0]==4'd7))
			 lowalarm<=1;
			 else
			 begin
			 lowalarm<=0;
			 end
			end
			if(out[3:0]==4'd4 && out[3:0]==4'd9)
				lowalarm<=1;
		end
	end
end

assign highalarm=((out[15:12]==4'd5)&&(out[11:8]==9)&&(out[7:4]==4'd5)&&(out[3:0]==4'd9))?1:0;
*/

endmodule
